﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using dm;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using log4net;
using System.Timers;
using System.IO;

namespace WindowsFormsApp1
{
    public enum Game_state
    {
        Idle = 0,
        Waiting_Game_Start = 1,
        Recognize_Villain_Position = 2,
        Recognize_D = 3,
        Hero_D = 4,
        Villain_D = 5,
        Recognize_Self_Poker = 6,
        Recognize_In_Which_Stage = 7,
        Hero_Stage = 8,
        Villain_Stage = 9,
        Preflop_Flop_Turn_River = 10,
        Preflop = 11,
        Flop = 12,
        Turn = 13,
        River = 14,
        Send_Info_To_Server_AI = 15,
        Wait_Server_AI_return = 16,
        AI_Timeout = 17,
        Execute_AI_Command = 18,
        Wait_AI_Command_Done = 19,
        Opponent_Decision_Done = 20,

    };

    public enum Hero_is_D
    {
        Hero_Stage = 0,
        Villain_Stage = 1,
        Recognize_Villain_Chip = 2,
        Wait_Game_Over = 3,
        Flop = 4,
        Turn = 5,
        River = 6,
        Ask_AI = 7,
        Exe_AI_Cmd = 8,
    };

    public enum Villain_is_D
    {
        Hero_Stage = 0,
        Villain_Stage_Over = 1,
        Villain_Stage = 2,
        Wait_Game_Over = 3,
        Flop = 4,
        Turn = 5,
        River = 6,
        Ask_AI = 7,
        Exe_AI_Cmd = 8,
    };

    public partial class Form1 : Form
    {
        static Game_state current_state = Game_state.Idle;
        static Hero_is_D Hero_is_D_state = Hero_is_D.Recognize_Villain_Chip;
        static Villain_is_D Villain_is_D_state = Villain_is_D.Hero_Stage;

        static dm.dmsoft dm = new dm.dmsoft();

        static window_info main_window = new window_info();
        static Graphics g = null;

        static Player[] players = new Player[6];
        static Message message;

        static int ante = 0;
        static int blind = 0;

        Thread Main_State_Machine = new Thread(State_Machine);

        static Queue message_to_display = new Queue();

        static Socket tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        static IPEndPoint serverAddress = new IPEndPoint(IPAddress.Parse("116.62.161.147"), 11000);

        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public Form1()
        {
            InitializeComponent();
            g = pictureBox1.CreateGraphics(); //创建画板，这里画板由Form提供的
            AutoRegCom("regsvr32 -s dm.dll");
            string dm_state = dm.Reg("hamigua0b548e8d6864e2a189fe6d81a6302d8b", "ruw2").ToString();
            string dm_ver = dm.Ver().ToString();
            string dm_res_path = System.Environment.CurrentDirectory + "\\file";
            int result = dm.SetPath(dm_res_path);
            dm_res_path = dm.GetPath();
            this.Text = string.Format("{0}  version-{1}  account_info:{2}", "大漠工具", dm_ver, dm_state);
            string res = string.Format("dm.dll 资源路径：{0}\r\n", dm_res_path);
            richTextBox1.AppendText(res);

            for (int j = 0; j < 6; j++)
            {
                players[j] = new Player();
            }

            // 先清空区域
            dm.SetExcludeRegion(2, "");

            // 添加区域
            dm.SetExcludeRegion(0, "115,250,245,285");

            //dm.SetColGapNoDict(0);
            //设置字库
            //self poker 和 public poker的数字
            string path = System.Environment.CurrentDirectory + "\\字库截图\\手牌\\";
            dm.SetDict(0, path + "card.txt");
            //self poker 的花色
            dm.SetDict(1, path + "card_type.txt");

            //公共poker的花色，分别对应第1张public poker，第2张public poker。。。。。
            path = System.Environment.CurrentDirectory + "\\字库截图\\公共牌\\";
            for (int i = 0; i < 5; i++)
            {
                dm.SetDict(i+2, string.Format(path + "card_type_{0}.txt", i));
            }

            //player的筹码，分别对应0,1,2,3,4,5player的筹码
            path = System.Environment.CurrentDirectory + "\\字库截图\\筹码\\";
            for (int i = 0; i < 6; i++)
            {
                dm.SetDict(i+7, string.Format(path + "{0}\\筹码{1}.txt", i, i));
            }

            //player的raise筹码，分别对应0,1,2,3,4,5player的筹码
            path = System.Environment.CurrentDirectory + "\\字库截图\\raise筹码\\";
            for (int i = 0; i < 6; i++)
            {
                dm.SetDict(i + 13, string.Format(path + "{0}\\raise筹码{1}.txt", i, i));
            }

            //raise
            path = System.Environment.CurrentDirectory + "\\字库截图\\hero_raise_chip\\";
            for (int i = 0; i < 3; i++)
            {
                dm.SetDict(i + 19, string.Format(path + "{0}\\raise筹码.txt", i));
            }
        }

        static string AutoRegCom(string strCmd)
        {
            string rInfo;
            try
            {
                Process myProcess = new Process();
                ProcessStartInfo myProcessStartInfo = new ProcessStartInfo("cmd.exe");
                myProcessStartInfo.UseShellExecute = false;
                myProcessStartInfo.CreateNoWindow = true;
                myProcessStartInfo.RedirectStandardOutput = true;
                myProcess.StartInfo = myProcessStartInfo;
                myProcessStartInfo.Arguments = "/c " + strCmd;
                myProcess.Start();
                StreamReader myStreamReader = myProcess.StandardOutput;
                rInfo = myStreamReader.ReadToEnd();
                myProcess.Close();
                rInfo = strCmd + "\r\n" + rInfo;
                return rInfo;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            if (button1.Text == "绑定")
            {
                main_window.window_handle = int.Parse(textBox1.Text);
                int result = dm.GetWindowRect(main_window.window_handle, out object x1, out object y1, out object x2, out object y2);
                main_window.window_position = new int[4] { (int)x1, (int)y1, (int)x2, (int)y2 };
                result = dm.BindWindowEx(main_window.window_handle, "dx2", "windows", "normal", "", 0);
                string res = string.Format("调用dm.dll结果:{0} 绑定句柄:{1} 窗口大小:{2}*{3}\r\n", result, main_window.window_handle, (int)x2 - (int)x1, (int)y2 - (int)y1);
                richTextBox1.AppendText(res);
                if(result ==1)
                {
                    button1.Text = "解除绑定";
                }
            }
            else
            {
                int result = dm.UnBindWindow();
                string res = string.Format("调用dm.dll结果:{0} 解除绑定句柄:{1}\r\n", result, main_window.window_handle);
                richTextBox1.AppendText(res);
                if (result == 1)
                {
                    button1.Text = "绑定";
                }
            }
        }

        private void textBox1_MouseDown(object sender, MouseEventArgs e)
        {

        }

        private void textBox1_MouseUp(object sender, MouseEventArgs e)
        {
            dm.GetCursorPos(out object x, out object y);
            int handle = dm.GetPointWindow((int)x, (int)y);
            textBox1.Text = handle.ToString();
            int result = dm.GetWindowRect(handle, out object x1, out object y1, out object x2, out object y2);
            string res = string.Format("调用dm.dll结果:{0} 获得句柄:{1} 窗口大小:{2}*{3}\r\n", result, handle, (int)x2 - (int)x1, (int)y2 - (int)y1);
            richTextBox1.AppendText(res);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
            log.Info("测试");
        }

        static private int calculate_player_position_accoding_xy(int x ,int y)
        {
            if (x > 100 && x < 240 && y > 0 && y < 100)
            {
                return 3;
            }
            else if(x > 278 && x < 360 && y > 135 && y < 215)
            {
                return 4;
            }
            else if (x > 278 && x < 360 && y > 310 && y < 420)
            {
                return 5;
            }
            else if (x > 128 && x < 235 && y > 455 && y < 525)
            {
                return 0;
            }
            else if (x > 1 && x < 100 && y > 300 && y < 415)
            {
                return 1;
            }
            else if (x > 1 && x < 100 && y > 110 && y < 220)
            {
                return 2;
            }
            return -1;
        }
        private bool My_stage()
        {
            return false;

        }

        static public string player_action(int index)
        {
            string action = null;
            switch (index)
            {
                //下注
                case 0:
                    action = "r";
                    break;
                //加注
                case 1:
                    action = "r";
                    break;
                //看牌
                case 2:
                    action = "k";
                    break;
                //弃牌
                case 3:
                    action = "f";
                    break;
                //跟注
                case 4:
                    action = "c";
                    break;
                //Allin
                case 5:
                    action = "s";
                    break;
                case 100:
                    action = "等待";
                    break;
                case 101:
                    action = "暂离";
                    break;
                default:
                    action = null;
                    break;
            }
            return action;
        }
        private void update_player_info_to_main_form()
        {
            string str = "";
            for (int i = 0; i < players.Length; i++)
            {
                str += string.Format("player{0}\r\n", i);
                str += string.Format("card:({0})    ", players[i].card);
                str += string.Format("chip:({0})    ", players[i].chip);
                str += string.Format("action:({0})\r\n\r\n", players[i].action);
            }
            str += string.Format("public_card:  {0}\r\n", message.public_card);
            richTextBox2.Text = str;
        }

        static private int determine_in_which_player_stage()
        {
            if (dm.CmpColor(main_window.player0_decision_stage_flag_position[0], main_window.player0_decision_stage_flag_position[1], "E03939-000101", 0.8) == 0)//进入我方扑克识别阶段
            {
                //我方阶段
                return 0;
            }
            else
            {
                if(dm.CmpColor(main_window.player0_decision_stage_flag_position[0], main_window.player0_decision_stage_flag_position[1], "A09F9F-010101", 0.8) == 0)
                {
                    return 1;
                }
                return -1;
            }
        }

        static private int Recognize_D()
        {
            int position = -1;
            string result = dm.FindPicEx(0, 0, 360, 640, "D0.bmp|D1.bmp|D2.bmp|D3.bmp|D4.bmp|D5.bmp", "101010", 0.9, 0);
            if (result != "")
            {
                string[] temp2 = result.Split(new char[1] { ',' });
                int x = int.Parse(temp2[1]);
                int y = int.Parse(temp2[2]);

                position = calculate_player_position_accoding_xy(x, y);

                //Rectangle r = new Rectangle(x, y, 10, 10);//是创建画矩形的区域  
                //g.DrawRectangle(Pens.Black, r);//g对象提供了画图形的方法，我们只需调用即可

                position = calculate_player_position_accoding_xy(x, y);
            }
            return position;
        }

        static private int Recognize_and_mark_villain_positions()
        {
            string result = dm.FindPicEx(0, 0, 360, 640, "有人0.bmp|有人1.bmp|有人2.bmp|有人3.bmp|有人4.bmp|有人5.bmp", "000000", 0.93, 0);
            if (result != "")
            {
                string[] temp = result.Split(new char[1] { '|' });
                for (int i = 0; i < temp.Length; i++)
                {
                    string[] temp2 = temp[i].Split(new char[1] { ',' });
                    int x = int.Parse(temp2[1]);
                    int y = int.Parse(temp2[2]);

                    Rectangle r = new Rectangle(x, y, 40, 40);//是创建画矩形的区域  
                    g.DrawRectangle(Pens.Blue, r);//g对象提供了画图形的方法，我们只需调用即可

                    int position = calculate_player_position_accoding_xy(x ,y);
                    if (position != 0 && position != -1)
                    {
                        return position;
                    }
                }
            }
            return -1;
        }

        static private Boolean Recognize_Game_Start()
        {
            string result = dm.FindPicEx(128, 125, 228, 196, "牌局开始标志.bmp", "303030", 0.7, 0);
            if (result != "")
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        static private void Recognize_and_mark_ready_players()
        {
            string result = dm.FindPicEx(0, 0, 360, 640, "等待中.bmp", "202020", 0.7, 0);
            if (result != "")
            {
                string[] temp = result.Split(new char[1] { '|' });
                for (int i = 0; i < temp.Length; i++)
                {
                    string[] temp2 = temp[i].Split(new char[1] { ',' });
                    int action = int.Parse(temp2[0]);
                    int x = int.Parse(temp2[1]);
                    int y = int.Parse(temp2[2]);

                    Rectangle r = new Rectangle(x, y, 40, 40);//是创建画矩形的区域  
                    g.DrawRectangle(Pens.Blue, r);//g对象提供了画图形的方法，我们只需调用即可

                    int position = calculate_player_position_accoding_xy(x, y);
                    if (position != -1)
                    {
                        players[position].action = "等待中";
                    }
                }
                //update_player_info_to_main_form();
            }
        }

        static private void Recognize_and_mark_temporary_leave_players()
        {
            string result = dm.FindPicEx(0, 0, 360, 640, "暂离.bmp", "202020", 0.7, 0);
            if (result != "")
            {
                string[] temp = result.Split(new char[1] { '|' });
                for (int i = 0; i < temp.Length; i++)
                {
                    string[] temp2 = temp[i].Split(new char[1] { ',' });
                    int action = int.Parse(temp2[0]);
                    int x = int.Parse(temp2[1]);
                    int y = int.Parse(temp2[2]);

                    Rectangle r = new Rectangle(x, y, 40, 40);//是创建画矩形的区域  
                    g.DrawRectangle(Pens.Blue, r);//g对象提供了画图形的方法，我们只需调用即可

                    int position = calculate_player_position_accoding_xy(x, y);
                    if (position != -1)
                    {
                        players[position].action = "暂离";
                    }
                }
                //update_player_info_to_main_form();
            }
        }


        static private string Recognize_player0_poker()
        {
            string[] s = new string[4];
            for (int i = 0; i < 4; i = i + 2)
            {
                //第i张公共牌
                dm.UseDict(0);
                int x0 = main_window.player0_card_positions[i, 0];
                int y0 = main_window.player0_card_positions[i, 1];
                int x00 = x0 + main_window.card_num_size[0];
                int y00 = y0 + main_window.card_num_size[1];
                s[i] = dm.Ocr(x0, y0, x00, y00, "7d6262-7D6363", 0.8);

                //第i张公共牌牌花色
                dm.UseDict(1);
                x0 = main_window.player0_card_positions[i + 1, 0];
                y0 = main_window.player0_card_positions[i + 1, 1];
                x00 = x0 + main_window.card_type_size[0];
                y00 = y0 + main_window.card_type_size[1];
                s[i + 1] = dm.Ocr(x0, y0, x00, y00, "b@7d6262-7D6363", 0.95);
            }
            return string.Format("{0}{1}{2}{3}", s[0], s[1], s[2], s[3]);             
        }

        //识别player raise chip
        static private int Recognize_player_raise_chip(int i)
        {
            string s_chip = "";
            try
            {
                //第i个player的raise筹码
                dm.UseDict(13 + i);
                int x0 = main_window.player_raise_chip_position[i, 0];
                int y0 = main_window.player_raise_chip_position[i, 1];
                int x00 = x0 + main_window.raise_chip_size[0];
                int y00 = y0 + main_window.raise_chip_size[1];
                string temp0 = dm.FindStrFastExS(x0, y0, x00, y00, "0|1|2|3|4|5|6|7|8|9", main_window.player_raise_chip_color_range[i], 0.85);
                string[] temp = temp0.Split(new char[1] { '|' });
                for (int j = 0; j < temp.Length; j++)
                {
                    string[] temp2 = temp[j].Split(new char[1] { ',' });
                    s_chip += temp2[0];
                }
                return int.Parse(s_chip);
            }
            catch (Exception e)
            {
                message_to_display.Enqueue(e);
                message_to_display.Enqueue("s_chip : " + s_chip);
                //richTextBox1.AppendText(e.Message);
            }
            return -1;
        }

        //识别player筹码
        static private int Recognize_player_chip(int i)
        {
            string s_chip = "";
            try
            {
                //第i个player的筹码
                dm.UseDict(7 + i);
                int x0 = main_window.player_chip_position[i, 0];
                int y0 = main_window.player_chip_position[i, 1];
                int x00 = x0 + main_window.chip_size[0];
                int y00 = y0 + main_window.chip_size[1];
                string temp0 = dm.FindStrFastExS(x0, y0, x00, y00, "0|1|2|3|4|5|6|7|8|9", main_window.player_chip_color_range[i], 0.85);
                string[] temp = temp0.Split(new char[1] { '|' });
                for (int j = 0; j < temp.Length; j++)
                {
                    string[] temp2 = temp[j].Split(new char[1] { ',' });
                    s_chip += temp2[0];
                }
                return int.Parse(s_chip);
            }
            catch (Exception e)
            {
                message_to_display.Enqueue(e);
                //richTextBox1.AppendText(e.Message);
            }
            return -1;
        }

        static private string Recognize_players_chip_before_start()
        {
            string[] s = new string[6];
            for (int i = 0; i < 2; i++)
            {
                //第i个player的筹码
                dm.UseDict(7 + i);
                int x0 = main_window.player_chip_position_s[i, 0];
                int y0 = main_window.player_chip_position_s[i, 1];
                int x00 = x0 + main_window.chip_size[0];
                int y00 = y0 + main_window.chip_size[1];
                s[i] = dm.FindStrFastExS(x0, y0, x00, y00, "0|1|2|3|4|5|6|7|8|9", main_window.player_chip_color_range_s[i], 0.85);
                string[] temp = s[i].Split(new char[1] { '|' });
                string s_chip = "";
                for (int j = 0; j < temp.Length; j++)
                {
                    string[] temp2 = temp[j].Split(new char[1] { ',' });
                    s_chip += temp2[0];
                }
                players[i].chip = int.Parse(s_chip);
            }
            return string.Format("{0}|{1}|{2}|{3}|{4}|{5}", s[0], s[1], s[2], s[3], s[4], s[5]);
        }

        static private string Recognize_Opponent_Action(int i)
        {
            //第i个player的动作    
            int x0 = main_window.player_action_position[i, 0];
            int y0 = main_window.player_action_position[i, 1];
            int x00 = x0 + main_window.action_size[0];
            int y00 = y0 + main_window.action_size[1];
            string action = null;

            string str = string.Format("下注{0}.bmp|加注{1}.bmp|看牌{2}.bmp|弃牌{3}.bmp|跟注{4}.bmp|Allin{5}.bmp", i, i, i, i, i, i);
            string result = dm.FindPicEx(x0, y0, x00, y00, str, "303030", 0.7, 0);
            if (result != "")
            {
                string[] temp = result.Split(new char[1] { '|' });
                for (int j = 0; j < temp.Length; j++)
                {
                    string[] temp2 = temp[j].Split(new char[1] { ',' });
                    int play_action = int.Parse(temp2[0]);
                    int x = int.Parse(temp2[1]);
                    int y = int.Parse(temp2[2]);
                    action = player_action(play_action);
                }
            }
            return action;
        }

        static private string Recognize_public_poker()
        {
            string[] s = new string[10];
            for (int i = 0; i < 10; i=i+2)
            {
                //第i张公共牌
                dm.UseDict(0);
                int x0 = main_window.public_card_positions[i, 0];
                int y0 = main_window.public_card_positions[i, 1];
                int x00 = x0 + main_window.card_num_size[0];
                int y00 = y0 + main_window.card_num_size[1];
                s[i] = dm.Ocr(x0, y0, x00, y00, "7d6262-7D6363", 0.85);

                //第i张公共牌牌花色
                if (i == 0)
                {
                    dm.UseDict(2);
                }
                else if (i == 2)
                {
                    dm.UseDict(3);
                }
                else if (i == 4)
                {
                    dm.UseDict(4);
                }
                else if (i == 6)
                {
                    dm.UseDict(5);
                }
                else if (i == 8)
                {
                    dm.UseDict(6);
                }
                Thread.Sleep(200);
                x0 = main_window.public_card_positions[i+1, 0];
                y0 = main_window.public_card_positions[i+1, 1];
                x00 = x0 + main_window.card_type_size[0];
                y00 = y0 + main_window.card_type_size[1];
                s[i+1] = dm.Ocr(x0, y0, x00, y00, "b@7d6262-7D6363", 0.95);
            }
            string result = string.Format("{0}{1} {2}{3} {4}{5} {6}{7} {8}{9}", s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9]);
            return result;

        }

        private static int Get_Raise_Chip(int i)
        {
            int raise_chip = -1;
            try
            {
                dm.UseDict(19 + i);
                int x0 = main_window.hero_raise_chip_position[i,0];
                int y0 = main_window.hero_raise_chip_position[i,1];
                int x00 = x0 + main_window.hero_raise_chip_position_size[0];
                int y00 = y0 + main_window.hero_raise_chip_position_size[1];
                string ss = dm.FindStrFastExS(x0, y0, x00, y00, "0|1|2|3|4|5|6|7|8|9", main_window.hero_raise_chip_position_color_range[i], 0.8);
                string[] temp = ss.Split(new char[1] { '|' });
                string s_chip = "";
                for (int j = 0; j < temp.Length; j++)
                {
                    string[] temp2 = temp[j].Split(new char[1] { ',' });
                    s_chip += temp2[0];
                }
                raise_chip = int.Parse(s_chip);
            }
            catch (Exception e)
            {
                message_to_display.Enqueue(e.Message);
            }
            return raise_chip;
        }

        private static void Hero_Raise_Action(int chip)
        {
            //Get_Raise_Chip
        }

        
        /*
        private static int[] Recognize_player0_can_raise_chip()
        {
            for (int i = 0; i < 3; i++)
            {
                //hero可以raise的chip
                //dm.UseDict(7 + i);
                int x0 = main_window.hero_raise_chip_position[i, 0];
                int y0 = main_window.hero_raise_chip_position[i, 1];
                int x00 = x0 + main_window.hero_raise_chip_position_size[0];
                int y00 = y0 + main_window.hero_raise_chip_position_size[1];
                string s = dm.FindStrFastExS(x0, y0, x00, y00, "0|1|2|3|4|5|6|7|8|9", main_window.hero_raise_chip_position_color_range[i], 0.85);
                string[] temp = s.Split(new char[1] { '|' });
                string s_chip = "";
                for (int j = 0; j < temp.Length; j++)
                {
                    string[] temp2 = temp[j].Split(new char[1] { ',' });
                    s_chip += temp2[0];
                }
                message.hero_can_raise_chip[i] = int.Parse(s_chip);
            }
        }*/

        static private void send_msg_to_AI(string msg)
        {
            try
            {
                tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                tcpClient.Connect(serverAddress);
                int toSendLen = Encoding.ASCII.GetByteCount(msg);
                byte[] toSendBytes = Encoding.ASCII.GetBytes(msg);
                byte[] toSendLenBytes = BitConverter.GetBytes(toSendLen);
                tcpClient.Send(toSendLenBytes);
                tcpClient.Send(toSendBytes);
            }
            catch (Exception ex)
            {
                message_to_display.Enqueue(ex.Message);
            }
        }

        static private string rec_msg_from_AI()
        {
            string rcv = "";
            try
            {
                byte[] rcvLenBytes = new byte[4];
                tcpClient.Receive(rcvLenBytes);
                int rcvLen = BitConverter.ToInt32(rcvLenBytes, 0);
                byte[] rcvBytes = new byte[rcvLen];
                tcpClient.Receive(rcvBytes);
                rcv = Encoding.ASCII.GetString(rcvBytes);
                tcpClient.Close();
            }
            catch (Exception ex)
            {
                message_to_display.Enqueue(ex.Message);
            }
            return rcv;
        }

        static private void execute_AI_command(string action)
        {
            log.Info("execute_AI_command:" + action);
            string[] temp = action.Split(new char[1] { '.' });
            switch (temp[1])
            {
                case "f":
                    dm.MoveTo(91, 528);
                    dm.LeftClick();

                    Thread.Sleep(1000);

                    dm.MoveTo(236, 329);
                    dm.LeftClick();
                    break;
                case "c":
                    dm.MoveTo(268, 528);
                    dm.LeftClick();
                    message.Hero_action = "H.c";

                    break;
                case "k":
                    dm.MoveTo(268, 528);
                    dm.LeftClick();
                    message.Hero_action = "H.k";

                    break;
                case "s":
                    dm.MoveTo(180, 504);
                    dm.LeftDown();
                    dm.MoveTo(180, 167);
                    dm.LeftUp();
                    message.Hero_action = "H.s";

                    break;
                default:
                    if (temp[1].Contains("r"))
                    {
                        int raise_chip = int.Parse(temp[1].Substring(1));

                        log.Info("hero_can_raise_chip:" + message.hero_can_raise_chip[0]);
                        log.Info("hero_can_raise_chip:" + message.hero_can_raise_chip[1]);
                        log.Info("hero_can_raise_chip:" + message.hero_can_raise_chip[2]);


                        if (message.hero_can_raise_chip[0] < message.hero_can_raise_chip[1] && message.hero_can_raise_chip[1] < message.hero_can_raise_chip[2])
                        {

                            int[] distance = { Math.Abs(raise_chip - message.hero_can_raise_chip[0]), Math.Abs(raise_chip - message.hero_can_raise_chip[1]), Math.Abs(raise_chip - message.hero_can_raise_chip[2])};
                            int min_index = Array.IndexOf(distance, distance.Min());
                            log.Info("choose:" + min_index);
                            if (min_index == 0)
                            {
                                dm.MoveTo(118, 442);
                                dm.LeftClick();

                                message.Hero_action = "H.r" + raise_chip.ToString();

                            }
                            else if (min_index == 1)
                            {
                                dm.MoveTo(180, 442);
                                dm.LeftClick();

                                message.Hero_action = "H.r" + raise_chip.ToString();

                            }
                            else if (min_index == 2)
                            {
                                dm.MoveTo(243, 442);
                                dm.LeftClick();

                                message.Hero_action = "H.r" + raise_chip.ToString();

                            }
                            else
                            {
                                dm.MoveTo(91, 528);
                                dm.LeftClick();
                            }
                        }
                        else
                        {
                            dm.MoveTo(91, 528);
                            dm.LeftClick();
                        }
                    }
                    break;
            }
        }

        private static void Recognize_Public_Card()
        {
            message.public_card = Recognize_public_poker();
            message.public_card = Recognize_public_poker();
            message.public_card = Recognize_public_poker();
            message_to_display.Enqueue(message.public_card);
            string[] temp = message.public_card.Split(new char[1] { ' ' });
            message.flop_board = temp[0] + temp[1] + temp[2];
            message.turn_board = temp[3];
            message.river_board = temp[4];
        }
        private static void State_Machine()
        {
            while (true)
            {
                //Thread.Sleep(500);
                //log.Info("----------------------------" + current_state.ToString() + "----------------------------");
                switch (current_state)
                {
                    case Game_state.Idle:
                        log.Info("------------------------------------------------------new hand--------------------------------------------");
                        current_state = Game_state.Waiting_Game_Start;
                        break;

                    case Game_state.Waiting_Game_Start:
                        current_state = Game_state.Waiting_Game_Start;
                        if (Recognize_Game_Start())
                        {
                            Thread.Sleep(1000);

                            message_to_display.Enqueue("\r\n");

                            //新的message
                            message = new Message(DateTime.Now.TimeOfDay.Ticks.ToString(), ante, blind);

                            //初始化 players 信息
                            for (int j = 0; j < 6; j++)
                            {
                                players[j] = new Player();
                            }

                            current_state = Game_state.Recognize_Villain_Position;
                            Hero_is_D_state = Hero_is_D.Recognize_Villain_Chip;
                            Villain_is_D_state = Villain_is_D.Hero_Stage;
                        }
                        else
                        {
                            current_state = Game_state.Waiting_Game_Start;
                        }
                        break;

                    case Game_state.Recognize_Villain_Position:
                        current_state = Game_state.Recognize_Villain_Position;

                        //画布初始化
                        g.Clear(SystemColors.Control);

                        //识别本局可用的（位置）
                        message.villain_position = Recognize_and_mark_villain_positions();

                        if (message.villain_position != -1)
                        {
                            current_state = Game_state.Recognize_D;
                        }

                        break;
                    case Game_state.Recognize_D:
                        current_state = Game_state.Recognize_D;

                        Thread.Sleep(1000);

                        //识别D的位置
                        int position = Recognize_D();
                        if (position != -1)
                        {
                            if (position == 0)
                            {
                                current_state = Game_state.Hero_D;
                            }
                            else
                            {
                                current_state = Game_state.Villain_D;
                                Thread.Sleep(2000);
                            }
                        }
                        break;
                    case Game_state.Hero_D:
                        current_state = Game_state.Hero_D;

                        players[0].is_D = true;
                        players[message.villain_position].is_D = false;

                        message.Hero_position = "S";



                        //log.Info("------------------------------------------------------In  " + Hero_is_D_state.ToString() + "----------------------------");
                        switch (Hero_is_D_state)
                        {
                            case Hero_is_D.Recognize_Villain_Chip:
                                
                                Hero_is_D_state = Hero_is_D.Villain_Stage;

                                break;

                            case Hero_is_D.Villain_Stage:
                                //Thread.Sleep(500);
                                string action = Recognize_Opponent_Action(message.villain_position);
                                //log.Info("识别的对手action：" + action);

                                Recognize_Public_Card();

                                if (message.flop_board != "" && message.flop_board_added == false)
                                {
                                    message.add_message_to_send("V.c");
                                    Hero_is_D_state = Hero_is_D.Flop;
                                }

                                if (message.turn_board != "" && message.turn_board_added == false)
                                {
                                    message.add_message_to_send("V.c");
                                    Hero_is_D_state = Hero_is_D.Turn;
                                }

                                if (message.river_board != "" && message.river_board_added == false)
                                {
                                    message.add_message_to_send("V.c");
                                    Hero_is_D_state = Hero_is_D.River;
                                }

                                message.which_player_stage = determine_in_which_player_stage();
                                if (message.which_player_stage != -1)
                                {
                                    switch (message.which_player_stage)
                                    {
                                        case 0:
                                            action = Recognize_Opponent_Action(message.villain_position);
                                            message_to_display.Enqueue("识别的对手action：" + action);
                                            log.Info("识别的对手action：" + action);
                                            if (action != null)
                                            {
                                                message.Villain_action = action;
                                                players[message.villain_position].action = message.Villain_action;

                                                if (message.Villain_action == "r")
                                                {
                                                    int raise_chip = Recognize_player_raise_chip(message.villain_position);
                                                    message.Villain_action = string.Format("V.r{0}", raise_chip);
                                                }
                                                else
                                                {
                                                    message.Villain_action = string.Format("V.{0}", message.Villain_action);
                                                }

                                                Hero_is_D_state = Hero_is_D.Hero_Stage;
                                            }
                                            break;
                                        default:
                                            //Hero_is_D_state = Hero_is_D.Villain_Stage;
                                            break;
                                    }  
                                }
                                break;

                            case Hero_is_D.Hero_Stage:

                                //识别我方可以raise的筹码
                                message.hero_can_raise_chip[0] = Get_Raise_Chip(0);
                                message.hero_can_raise_chip[1] = Get_Raise_Chip(1);
                                message.hero_can_raise_chip[2] = Get_Raise_Chip(2);
                                message_to_display.Enqueue(message.hero_can_raise_chip[0]);
                                message_to_display.Enqueue(message.hero_can_raise_chip[1]);
                                message_to_display.Enqueue(message.hero_can_raise_chip[2]);

                                //识别我方手牌
                                players[0].card = Recognize_player0_poker();
                                message.hand = players[0].card;

                               
                                if (message.Villain_action.Contains("f"))
                                {
                                    Hero_is_D_state = Hero_is_D.Wait_Game_Over;
                                }

                                if (message.Villain_action.Contains("s") || message.Villain_action.Contains("r") || message.Villain_action.Contains("c") || message.Villain_action.Contains("k"))
                                {
                                    Hero_is_D_state = Hero_is_D.Ask_AI;
                                }
                                break;

                            case Hero_is_D.Flop:

                                Thread.Sleep(2000);

                                Recognize_Public_Card();

                                message.poker_state = "Flop";

                                if (message.flop_board_added == false)
                                {
                                    message.flop_board_added = true;
                                    message.add_message_to_send("F." + message.flop_board);
                                }

                                Hero_is_D_state = Hero_is_D.Villain_Stage;

                                break;

                            case Hero_is_D.Turn:

                                Thread.Sleep(2000);

                                Recognize_Public_Card();

                                message.poker_state = "Turn";
                                if (message.turn_board_added == false)
                                {
                                    message.turn_board_added = true;
                                    message.add_message_to_send("T." + message.turn_board);
                                }

                                Hero_is_D_state = Hero_is_D.Villain_Stage;
                                break;

                            case Hero_is_D.River:

                                Thread.Sleep(2000);

                                Recognize_Public_Card();

                                message.poker_state = "River";
                                if (message.river_board_added == false)
                                {
                                    message.river_board_added = true;
                                    message.add_message_to_send("R." + message.river_board);
                                }

                                Hero_is_D_state = Hero_is_D.Villain_Stage;
                                break;


                            case Hero_is_D.Wait_Game_Over:

                                if (Recognize_Game_Start() == false)
                                {
                                    Thread.Sleep(1500);
                                    if (Recognize_Game_Start() == false)
                                    {
                                        current_state = Game_state.Idle;
                                    }
                                }
                                break;


                            case Hero_is_D.Ask_AI:

                                if (message.new_hand == true)
                                {
                                    Thread.Sleep(2000);
                                    message.new_hand = false;
                                    players[0].chip = Recognize_player_chip(0);
                                    players[message.villain_position].chip = Recognize_player_chip(message.villain_position);

                                    message.Hero_chip = players[0].chip + message.blind_chip + message.ante_chip;
                                    message.Villain_chip = players[message.villain_position].chip + message.ante_chip;

                                    message.add_message_to_send(message.Hero_chip.ToString());
                                    message.add_message_to_send(message.Villain_chip.ToString());
                                    message.add_message_to_send(message.Hero_position);
                                    message.add_message_to_send(message.hand);
                                    message.add_message_to_send(message.Villain_action);

                                    message_to_display.Enqueue(message.to_send);
                                    log.Info(message.to_send);

                                    send_msg_to_AI(message.to_send);
                                    message.AI_return = rec_msg_from_AI();

                                    log.Info(message.AI_return);

                                    //message_to_display.Enqueue(message.AI_return);
                                }
                                else
                                {
                                    message.add_message_to_send(message.Villain_action);
                                    message_to_display.Enqueue(message.to_send);
                                    log.Info(message.to_send);

                                    send_msg_to_AI(message.to_send);
                                    message.AI_return = rec_msg_from_AI();

                                    log.Info(message.AI_return);
                                    //message_to_display.Enqueue(message.AI_return);
                                }

                                //发送信息给AI




                                Hero_is_D_state = Hero_is_D.Exe_AI_Cmd;
                                break;

                            case Hero_is_D.Exe_AI_Cmd:

                                Thread.Sleep(500);
                                int Hero_action_index = message.AI_return.IndexOf("action");

                                if (Hero_action_index != -1)
                                {

                                    message.Hero_action = String.Format("H.{0}", message.AI_return.Substring(Hero_action_index + 7, 10).Split(new char[1] { '\r' })[0]);
                                    message.add_message_to_send(message.Hero_action);
                                    message_to_display.Enqueue("Hero_action : " + message.Hero_action);

                                    //Thread.Sleep(3000);
                                    execute_AI_command(message.Hero_action);

                                    if (message.Hero_action.Contains("r"))
                                    {
                                        Thread.Sleep(500);
                                        Hero_is_D_state = Hero_is_D.Villain_Stage;
                                    }

                                    if (message.Villain_action.Contains("s") || message.Hero_action.Contains("f") || message.Hero_action.Contains("s"))
                                    {
                                        Hero_is_D_state = Hero_is_D.Wait_Game_Over;
                                    }

                                    if(message.poker_state == null)
                                    {
                                        if ((message.Villain_action.Contains("r") && message.Hero_action.Contains("c")) || (message.Villain_action.Contains("c") && message.Hero_action.Contains("k")))
                                        {
                                            Hero_is_D_state = Hero_is_D.Flop;
                                        }
                                    }

                                    if (message.poker_state == "Flop")
                                    {
                                        if ((message.Villain_action.Contains("k") && message.Hero_action.Contains("k")) || (message.Villain_action.Contains("r") && message.Hero_action.Contains("c")))
                                        {
                                            Hero_is_D_state = Hero_is_D.Turn;
                                        }
                                    }

                                    if (message.poker_state == "Turn")
                                    {
                                        if ((message.Villain_action.Contains("k") && message.Hero_action.Contains("k")) || (message.Villain_action.Contains("r") && message.Hero_action.Contains("c")))
                                        {
                                            Hero_is_D_state = Hero_is_D.River;
                                        }
                                    }
                                }

                                //log.Info("------------------------------------------------------Out " + Hero_is_D_state.ToString() + "----------------------------");
                                break;
                        }

                        if (Recognize_Game_Start() == false)
                        {
                            Thread.Sleep(1500);
                            if (Recognize_Game_Start() == false)
                            {
                                current_state = Game_state.Idle;
                            }
                        }

                        break;
                    case Game_state.Villain_D:
                        current_state = Game_state.Villain_D;


                        players[0].is_D = false;
                        players[message.villain_position].is_D = true;

                        message.Hero_position = "B";

                        switch (Villain_is_D_state)
                        {
                            case Villain_is_D.Hero_Stage:

                                message.hero_can_raise_chip[0] = Get_Raise_Chip(0);
                                message.hero_can_raise_chip[1] = Get_Raise_Chip(1);
                                message.hero_can_raise_chip[2] = Get_Raise_Chip(2);
                                message_to_display.Enqueue(message.hero_can_raise_chip[0]);
                                message_to_display.Enqueue(message.hero_can_raise_chip[1]);
                                message_to_display.Enqueue(message.hero_can_raise_chip[2]);

                                if (message.new_hand == true)
                                {

                                    message.new_hand = false;
                                    players[0].card = Recognize_player0_poker();
                                    message.hand = players[0].card;

                                    players[0].chip = Recognize_player_chip(0);
                                    players[message.villain_position].chip = Recognize_player_chip(message.villain_position);

                                    message.Hero_chip = players[0].chip + message.ante_chip;
                                    message.Villain_chip = players[message.villain_position].chip + message.ante_chip + message.blind_chip;

                                    message.add_message_to_send(message.Hero_chip.ToString());
                                    message.add_message_to_send(message.Villain_chip.ToString());
                                    message.add_message_to_send(message.Hero_position);
                                    message.add_message_to_send(message.hand);



                                    //message_to_display.Enqueue(message.AI_return);
                                }
                                else
                                {
                                    //message.add_message_to_send(message.Villain_action);
                                    //message_to_display.Enqueue(message.AI_return);
                                }
                                Villain_is_D_state = Villain_is_D.Ask_AI;
                                break;
                            case Villain_is_D.Ask_AI:

                                message_to_display.Enqueue(message.to_send);
                                log.Info(message.to_send);

                                send_msg_to_AI(message.to_send);
                                message.AI_return = rec_msg_from_AI();

                                log.Info(message.AI_return);

                                Villain_is_D_state = Villain_is_D.Exe_AI_Cmd;
                                break;
                            case Villain_is_D.Exe_AI_Cmd:

                                Thread.Sleep(500);
                                int Hero_action_index = message.AI_return.IndexOf("action");

                                if (Hero_action_index != -1)
                                {

                                    message.Hero_action = String.Format("H.{0}", message.AI_return.Substring(Hero_action_index + 7, 10).Split(new char[1] { '\r' })[0]);
                                    message.add_message_to_send(message.Hero_action);
                                    message_to_display.Enqueue("Hero_action : " + message.Hero_action);

                                    //Thread.Sleep(3000);
                                    execute_AI_command(message.Hero_action);

                                    if (message.Hero_action.Contains("c") && message.Villain_action.Contains("r"))
                                    {
                                        Thread.Sleep(500);

                                        if (message.poker_state == null)
                                        {
                                            Villain_is_D_state = Villain_is_D.Flop;
                                        }

                                        if (message.poker_state == "Flop")
                                        {
                                            Villain_is_D_state = Villain_is_D.Turn;
                                        }

                                        if (message.poker_state == "Turn")
                                        {
                                            Villain_is_D_state = Villain_is_D.River;
                                        }
                                    }

                                    if (message.Hero_action.Contains("f") || message.Hero_action.Contains("s"))
                                    {
                                        Villain_is_D_state = Villain_is_D.Wait_Game_Over;
                                    }

                                    if (message.Hero_action.Contains("c") || message.Hero_action.Contains("r") || message.Hero_action.Contains("k"))
                                    {
                                        Villain_is_D_state = Villain_is_D.Villain_Stage;
                                        Thread.Sleep(500);
                                    }
                                }

                                break;
                            case Villain_is_D.Flop:
                                Thread.Sleep(2000);

                                Recognize_Public_Card();

                                message.poker_state = "Flop";

                                if (message.flop_board_added == false)
                                {
                                    message.flop_board_added = true;
                                    message.add_message_to_send("F." + message.flop_board);
                                }

                                Villain_is_D_state = Villain_is_D.Hero_Stage;
                                break;
                            case Villain_is_D.Turn:
                                Thread.Sleep(2000);

                                Recognize_Public_Card();

                                message.poker_state = "Turn";

                                if (message.turn_board_added == false)
                                {
                                    message.turn_board_added = true;
                                    message.add_message_to_send("T." + message.turn_board);
                                }

                                Villain_is_D_state = Villain_is_D.Hero_Stage;
                                break;
                            case Villain_is_D.River:

                                Thread.Sleep(2000);

                                Recognize_Public_Card();

                                message.poker_state = "River";

                                if (message.river_board_added == false)
                                {
                                    message.river_board_added = true;
                                    message.add_message_to_send("R." + message.river_board);
                                }

                                Villain_is_D_state = Villain_is_D.Hero_Stage;
                                break;
                            case Villain_is_D.Wait_Game_Over:
                                if (Recognize_Game_Start() == false)
                                {
                                    Thread.Sleep(1500);
                                    if (Recognize_Game_Start() == false)
                                    {
                                        current_state = Game_state.Idle;
                                    }
                                }
                                break;
                            case Villain_is_D.Villain_Stage:
                                message.which_player_stage = determine_in_which_player_stage();
                                if (message.which_player_stage != -1)
                                {
                                    switch (message.which_player_stage)
                                    {
                                        case 0:
                                            if (message.Villain_action != null)
                                            {
                                                players[message.villain_position].action = message.Villain_action;

                                                if (message.Villain_action.Contains("r"))
                                                {
                                                    int raise_chip = Recognize_player_raise_chip(message.villain_position);
                                                    message.Villain_action = string.Format("V.r{0}", raise_chip);
                                                }
                                                else
                                                {
                                                    message.Villain_action = string.Format("V.{0}", message.Villain_action);
                                                }

                                                log.Info("识别的对手action：" + message.Villain_action);
                                                message_to_display.Enqueue("识别的对手action：" + message.Villain_action);

                                                Villain_is_D_state = Villain_is_D.Villain_Stage_Over;
                                            }
                                            else
                                            {
                                                message.Villain_action = Recognize_Opponent_Action(message.villain_position);
                                            }
                                            break;
                                        default:
                                            message.Villain_action = Recognize_Opponent_Action(message.villain_position);
                                            //message_to_display.Enqueue("识别的对手action：" + message.Villain_action);
                                            //log.Info("识别的对手action：" + message.Villain_action);                     
                                            break;
                                    }
                                }
                                break;
                            case Villain_is_D.Villain_Stage_Over:

                                message.add_message_to_send(message.Villain_action);

                                if ((message.Hero_action.Contains("c") && message.Villain_action.Contains("k")) || (message.Hero_action.Contains("r") && message.Villain_action.Contains("c")))
                                {
                                    if(message.poker_state == null)
                                    {
                                        Villain_is_D_state = Villain_is_D.Flop;
                                    }
                                }

                                if ((message.Hero_action.Contains("k") && message.Villain_action.Contains("k")) || (message.Hero_action.Contains("r") && message.Villain_action.Contains("c")))
                                {
                                    if(message.poker_state == "Flop")
                                    {
                                        Villain_is_D_state = Villain_is_D.Turn;
                                    }

                                    if (message.poker_state == "Turn")
                                    {
                                        Villain_is_D_state = Villain_is_D.River;
                                    }
                                }

                                if (message.Villain_action.Contains("r"))
                                {
                                    Villain_is_D_state = Villain_is_D.Hero_Stage;
                                    Thread.Sleep(1000);
                                }


                                break;
                        }

                        if (Recognize_Game_Start() == false)
                        {
                            Thread.Sleep(1500);
                            if (Recognize_Game_Start() == false)
                            {
                                current_state = Game_state.Idle;
                            }
                        }

                        break;
                    //进入游戏等待阶段
                    case Game_state.Recognize_Self_Poker:
                        current_state = Game_state.Recognize_Self_Poker;

                        Thread.Sleep(1000);
                        //识别player0的扑克
                        string result = Recognize_player0_poker();
                        players[0].card = result;
                        message.hand = players[0].card;

                        //update_player_info_to_main_form();

                        current_state = Game_state.Recognize_In_Which_Stage;
                        break;

                    case Game_state.Recognize_In_Which_Stage:
                        current_state = Game_state.Recognize_In_Which_Stage;

                        Thread.Sleep(1000);
                        message.which_player_stage = determine_in_which_player_stage();
                        if (message.which_player_stage != -1)
                        {
                            switch (message.which_player_stage)
                            {
                                case 0:
                                    current_state = Game_state.Hero_Stage;
                                    break;
                                default:
                                    current_state = Game_state.Villain_Stage;
                                    break;
                            }
                        }

                        if (Recognize_Game_Start() == false)
                        {
                            Thread.Sleep(1500);
                            if (Recognize_Game_Start() == false)
                            {
                                current_state = Game_state.Waiting_Game_Start;
                            }
                        }
                        break;

                    //进入，我方决策阶段
                    case Game_state.Hero_Stage:
                        current_state = Game_state.Hero_Stage;

                        if (message.new_hand == true)
                        {
                            //Thread.Sleep(1000);
                            message.new_hand = false;
                            players[0].chip = Recognize_player_chip(0);
                            players[message.villain_position].chip = Recognize_player_chip(message.villain_position);

                            if (message.Hero_position == "B")
                            {
                                message.Hero_chip = players[0].chip + message.blind_chip + message.ante_chip;
                                message.Villain_chip = players[message.villain_position].chip + message.ante_chip;
                            }
                            else
                            {
                                message.Hero_chip = players[0].chip + message.blind_chip;
                                message.Villain_chip = players[message.villain_position].chip + message.ante_chip + message.blind_chip;
                            }

                            message.add_message_to_send(message.Hero_chip.ToString());
                            message.add_message_to_send(message.Villain_chip.ToString());
                            message.add_message_to_send(message.Hero_position);
                            message.add_message_to_send(message.hand);
                        }


                        message.hero_can_raise_chip[0] = Get_Raise_Chip(0);
                        message.hero_can_raise_chip[1] = Get_Raise_Chip(1);
                        message.hero_can_raise_chip[2] = Get_Raise_Chip(2);
                        message_to_display.Enqueue(message.hero_can_raise_chip[0]);
                        message_to_display.Enqueue(message.hero_can_raise_chip[1]);
                        message_to_display.Enqueue(message.hero_can_raise_chip[2]);

                        current_state = Game_state.Preflop_Flop_Turn_River;
                        break;
                    //进入，对手决策阶段
                    case Game_state.Villain_Stage:
                        current_state = Game_state.Villain_Stage;

                        //识别对手的action

                        //Thread.Sleep(1500);
                        
                        string action_temp = Recognize_Opponent_Action(message.villain_position);
                        if(action_temp != null)
                        {
                            message.Villain_action = action_temp;
                            players[message.villain_position].action = message.Villain_action;
                            current_state = Game_state.Opponent_Decision_Done;
                        }
                        


                        if (Recognize_Game_Start() == false)
                        {
                            Thread.Sleep(1500);
                            if (Recognize_Game_Start() == false)
                            {
                                current_state = Game_state.Waiting_Game_Start;
                            }
                        }
                        break;

                    case Game_state.Opponent_Decision_Done:
                        current_state = Game_state.Opponent_Decision_Done;
                        message.which_player_stage = determine_in_which_player_stage();
                        if (message.which_player_stage == 0)
                        {
                            action_temp = Recognize_Opponent_Action(message.villain_position);
                            if (action_temp != null)
                            {
                                message.Villain_action = action_temp;
                                players[message.villain_position].action = message.Villain_action;
                            }

                            current_state = Game_state.Recognize_In_Which_Stage;
                        }

                        if (Recognize_Game_Start() == false)
                        {
                            Thread.Sleep(1500);
                            if (Recognize_Game_Start() == false)
                            {
                                current_state = Game_state.Waiting_Game_Start;
                            }
                        }
                        break;

                    //Preflop_Flop_Turn_River
                    case Game_state.Preflop_Flop_Turn_River:
                        current_state = Game_state.Preflop_Flop_Turn_River;

                        Thread.Sleep(2000);
                        message.public_card = Recognize_public_poker();
                        string[] temp = message.public_card.Split(new char[1] { ' ' });
                        message.flop_board = temp[0] + temp[1] + temp[2];
                        message.turn_board = temp[3];
                        message.river_board = temp[4];

                        current_state = Game_state.Preflop;

                        if (message.flop_board != "")
                        {
                            current_state = Game_state.Flop;
                        }
                        if (message.turn_board != "")
                        {
                            current_state = Game_state.Turn;
                        }
                        if (message.river_board != "")
                        {
                            current_state = Game_state.River;
                        }
                        break;


                    case Game_state.Preflop:
                        current_state = Game_state.Preflop;


                        if (message.Villain_action != null)
                        {
                            if (message.Villain_action == "r")
                            {
                                int raise_chip = Recognize_player_raise_chip(message.villain_position);
                                message.add_message_to_send(string.Format("V.r{0}", raise_chip));
                            }
                            else
                            {
                                message.add_message_to_send(string.Format("V.{0}", message.Villain_action));
                            }
                            message.Villain_action = null;
                        }

                        message.poker_state = "Preflop";
                        current_state = Game_state.Send_Info_To_Server_AI;
                        break;

                    case Game_state.Flop:
                        current_state = Game_state.Flop;

                        message.poker_state = "Flop";
                        if (message.flop_board_added == false)
                        {
                            message.flop_board_added = true;
                            message.add_message_to_send(message.flop_board);
                        }

                        current_state = Game_state.Send_Info_To_Server_AI;
                        break;

                    case Game_state.Turn:
                        current_state = Game_state.Turn;

                        message.poker_state = "Turn";
                        if (message.turn_board_added == false)
                        {
                            message.turn_board_added = true;
                            message.add_message_to_send(message.turn_board);
                        }

                        current_state = Game_state.Send_Info_To_Server_AI;
                        break;

                    case Game_state.River:
                        current_state = Game_state.River;

                        message.poker_state = "River";
                        if (message.river_board_added == false)
                        {
                            message.river_board_added = true;
                            message.add_message_to_send(message.river_board);
                        }

                        current_state = Game_state.Send_Info_To_Server_AI;
                        break;


                    //发送信息到AI服务器
                    case Game_state.Send_Info_To_Server_AI:
                        current_state = Game_state.Send_Info_To_Server_AI;


                        message_to_display.Enqueue(message.to_send);

                        //发送信息给AI
                        send_msg_to_AI(message.to_send);

                        //进入识别公共poker阶段
                        current_state = Game_state.Wait_Server_AI_return;
                        break;

                    //等待AI服务器返回
                    case Game_state.Wait_Server_AI_return:
                        current_state = Game_state.Wait_Server_AI_return;
                        //Thread.Sleep(3000);

                        //等待AI返回
                        message.AI_return = rec_msg_from_AI();

                        message_to_display.Enqueue(message.AI_return);

                        current_state = Game_state.Execute_AI_Command;
                        break;

                    case Game_state.Execute_AI_Command:
                        current_state = Game_state.Execute_AI_Command;

                        Thread.Sleep(500);
                        int hero_action_index = message.AI_return.IndexOf("action");

                        if (hero_action_index != -1)
                        {
                            message.Hero_action = String.Format("H.{0}", message.AI_return.Substring(hero_action_index + 7, 10).Split(new char[1] { '\r' })[0]);
                            message.add_message_to_send(message.Hero_action);
                            message_to_display.Enqueue(message.to_send);
                            execute_AI_command(message.Hero_action);
                        }
                        
                        //Hero_Raise_Action(0);
                        current_state = Game_state.Wait_AI_Command_Done;
                        break;

                    case Game_state.Wait_AI_Command_Done:
                        current_state = Game_state.Wait_AI_Command_Done;

                        Thread.Sleep(2000);
                        //current_state = Game_state.Recognize_In_Which_Stage;
                        
                        message.which_player_stage = determine_in_which_player_stage();
                        if (message.which_player_stage != -1)
                        {
                            current_state = Game_state.Recognize_In_Which_Stage;
                            /*
                            switch (message.which_player_stage)
                            {
                                case 0:
                                    current_state = Game_state.Recognize_In_Which_Stage;
                                    break;
                                default:
                                    current_state = Game_state.Recognize_In_Which_Stage;
                                    break;
                            }
                            */
                        }

                        if (Recognize_Game_Start() == false)
                        {
                            Thread.Sleep(2000);
                            if (Recognize_Game_Start() == false)
                            {
                                current_state = Game_state.Waiting_Game_Start;
                            }
                        }
                        break;

                    default:
                        break;
                }
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            ante = int.Parse(textBox2.Text);
            blind = int.Parse(textBox3.Text);
            label3.Text = string.Format("主状态：{0}", current_state);
            while (message_to_display.Count != 0)
            {
                object t = message_to_display.Dequeue();
                if(t != null)
                {
                    richTextBox1.AppendText(t.ToString());
                    richTextBox1.AppendText("\r\n");

                    richTextBox1.SelectionStart = richTextBox1.Text.Length;
                    richTextBox1.SelectionLength = 0;
                    richTextBox1.Focus();
                }
            }

            if (message != null)
            {
                label18.Text = string.Format("牌局状态：{0}", Hero_is_D_state);
                label19.Text = string.Format("牌局状态：{0}", Villain_is_D_state);
            }


        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            int result = dm.GetCursorPos(out object x, out object y);
            label2.Text = string.Format("鼠标坐标：x({0}) y({1})", (int)x, (int)y);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //current_state = Game_state.Recognize_Positions;
        }

        //截图，我方poker，公共poker，筹码， raise筹码
        private void button3_Click(object sender, EventArgs e)
        {
            dm.EnableDisplayDebug(1);
            string log_path = System.Environment.CurrentDirectory + "\\字库截图\\";

            string path = log_path + "\\手牌\\";
            string now = DateTime.Now.TimeOfDay.Ticks.ToString();
            //player0 手牌 poker的数字和花色
            for (int i = 0; i < 4; i=i+2)
            {
                int x0 = main_window.player0_card_positions[i, 0];
                int y0 = main_window.player0_card_positions[i, 1];
                int x00 = x0 + main_window.card_num_size[0];
                int y00 = y0 + main_window.card_num_size[1];
                dm.Capture(x0, y0, x00, y00, string.Format(path + "{0}-{1}.bmp", now, i));

                x0 = main_window.player0_card_positions[i + 1, 0];
                y0 = main_window.player0_card_positions[i + 1, 1];
                x00 = x0 + main_window.card_type_size[0];
                y00 = y0 + main_window.card_type_size[1];
                dm.Capture(x0, y0, x00, y00, string.Format(path + "{0}-{1}.bmp", now, i + 1));
            }


            path = log_path + "\\公共牌\\";
            now = DateTime.Now.TimeOfDay.Ticks.ToString();
            //公共牌的 数字和花色
            for (int i = 0; i < 10; i = i + 2)
            {
                int x0 = main_window.public_card_positions[i, 0];
                int y0 = main_window.public_card_positions[i, 1];
                int x00 = x0 + main_window.card_num_size[0];
                int y00 = y0 + main_window.card_num_size[1];
                dm.Capture(x0, y0, x00, y00, string.Format(path + "{0}-{1}.bmp", now, i));

                x0 = main_window.public_card_positions[i + 1, 0];
                y0 = main_window.public_card_positions[i + 1, 1];
                x00 = x0 + main_window.card_type_size[0];
                y00 = y0 + main_window.card_type_size[1];
                dm.Capture(x0, y0, x00, y00, string.Format(path + "{0}-{1}.bmp", now, i + 1));
            }


            path = log_path + "\\筹码\\";
            now = DateTime.Now.TimeOfDay.Ticks.ToString();
            //筹码
            for (int i = 0; i < 6; i++)
            {
                int x0 = main_window.player_chip_position[i, 0];
                int y0 = main_window.player_chip_position[i, 1];
                int x00 = x0 + main_window.chip_size[0];
                int y00 = y0 + main_window.chip_size[1];
                dm.Capture(x0, y0, x00, y00, string.Format(path + "\\{0}\\{1}.bmp", i, now));

                x0 = main_window.player_chip_position_s[i, 0];
                y0 = main_window.player_chip_position_s[i, 1];
                x00 = x0 + main_window.chip_size[0];
                y00 = y0 + main_window.chip_size[1];
                dm.Capture(x0, y0, x00, y00, string.Format(path + "\\{0}\\{1}_s.bmp", i, now));
            }

            path = log_path + "\\raise筹码\\";
            now = DateTime.Now.TimeOfDay.Ticks.ToString();
            //raise筹码
            for (int i = 0; i < 6; i++)
            {
                int x0 = main_window.player_raise_chip_position[i, 0];
                int y0 = main_window.player_raise_chip_position[i, 1];
                int x00 = x0 + main_window.raise_chip_size[0];
                int y00 = y0 + main_window.raise_chip_size[1];
                dm.Capture(x0, y0, x00, y00, string.Format(path + "\\{0}\\{1}.bmp", i, now));
            }

            path = log_path + "\\hero_raise_chip\\";
            now = DateTime.Now.TimeOfDay.Ticks.ToString();
            //hero_raise_chip
            for (int i = 0; i < 3; i++)
            {
                int x0 = main_window.hero_raise_chip_position[i,0];
                int y0 = main_window.hero_raise_chip_position[i,1];
                int x00 = x0 + main_window.hero_raise_chip_position_size[0];
                int y00 = y0 + main_window.hero_raise_chip_position_size[1];
                dm.Capture(x0, y0, x00, y00, string.Format(path + "\\{0}\\{1}.bmp", i, now));
            }
            dm.EnableDisplayDebug(0);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            dm.EnableDisplayDebug(1);
            string log_path = System.Environment.CurrentDirectory + "\\log\\";
        }

        private void button4_Click_1(object sender, EventArgs e)
        {
            if (button4.Text == "设定")
            {
                textBox2.Enabled = false;
                textBox3.Enabled = false;
                button4.Text = "解除设定";
            }
            else
            {
                textBox2.Enabled = true;
                textBox3.Enabled = true;
                button4.Text = "设定";
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            current_state = Game_state.Waiting_Game_Start;
            Main_State_Machine.Start();
        }

        private void button6_Click(object sender, EventArgs e)
        {
            string action_temp = Recognize_Opponent_Action(message.villain_position);
            message_to_display.Enqueue("识别到的对手action：" + action_temp);

            message_to_display.Enqueue(Recognize_public_poker());
        }

        private void button7_Click(object sender, EventArgs e)
        {
            try
            {
                tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                tcpClient.Connect(serverAddress);
                groupBox5.Enabled = true;

                tcpClient.Close();
                message_to_display.Enqueue("服务器连接测试成功！");
            }
            catch (Exception ex)
            {
                groupBox5.Enabled = false;
                message_to_display.Enqueue(ex.Message);
            }
        }

        private void button8_Click(object sender, EventArgs e)
        {
            string toSend = "1 1.0 1.0 10.0 10.0 S 7sAc V.r3.0";

            IPEndPoint serverAddress = new IPEndPoint(IPAddress.Parse("116.62.161.147"), 11000);

            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            clientSocket.Connect(serverAddress);

            // Sending
            int toSendLen = Encoding.ASCII.GetByteCount(toSend);
            byte[] toSendBytes = Encoding.ASCII.GetBytes(toSend);
            byte[] toSendLenBytes = BitConverter.GetBytes(toSendLen);
            clientSocket.Send(toSendLenBytes);
            clientSocket.Send(toSendBytes);

            // Receiving
            byte[] rcvLenBytes = new byte[4];
            clientSocket.Receive(rcvLenBytes);
            int rcvLen = BitConverter.ToInt32(rcvLenBytes, 0);
            byte[] rcvBytes = new byte[rcvLen];
            clientSocket.Receive(rcvBytes);
            string rcv = Encoding.ASCII.GetString(rcvBytes);

            message_to_display.Enqueue(rcv);
            //Console.WriteLine("Client received:\n" + rcv);

            clientSocket.Close();
        }

        private void button9_Click(object sender, EventArgs e)
        {

        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBox1.SelectedIndex == 0)
            {

            }
            else
            {

            }
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            dm.UnBindWindow();
            tcpClient.Close();
            Main_State_Machine.Abort();
        }
    }


    public class window_info
    {
        public int window_handle;
        public int[] window_position = { 0, 0, 0, 0 };
        public int[] player0_decision_stage_flag_position = { 95, 518 };
        public int[,] player0_card_positions = { { 143, 568 }, { 155, 595 }, { 183, 568 }, { 194, 595 } };
        public int[,] public_card_positions = { { 85, 302 }, { 97, 330 }, 
                                                { 125, 302 }, { 136, 330 }, 
                                                { 164, 302 }, { 175, 330 }, 
                                                { 204, 302 }, { 215, 330 }, 
                                                { 243, 302 }, { 254, 330 }};
        public int[] card_num_size = { 20, 14 };
        public int[] card_type_size = { 23, 23 };

        public int[,] player_chip_position_s = { { 160, 538 }, { 11, 405 }, { 11, 215}, { 160, 91}, { 308, 215}, { 308, 405} };
        public int[,] player_chip_position = { { 158, 544 }, { 11, 405 }, { 11, 215 }, { 160, 91 }, { 308, 215 }, { 308, 405 } };
        public string[] player_chip_color_range_s = { "616B71-312928", "616B71-312928", "616B71-312928", "616B71-312928", "616B71-312928", "616B71-312928" };
        public string[] player_chip_color_range = { "bcc3c8-433C37", "C5CDD2-3A322D", "CED5D6-312A29", "B5C3C8-4A3C37", "C8CDD2-37322D", "B2BAC0-4D453F" };
        public int[] chip_size = { 44, 12 };

        public int[,] player_action_position = { { 170, 468 } ,{ 23, 336 }, { 23, 145}, { 172, 21}, { 279, 146}, { 279, 335} };
        public int[] action_size = { 60, 30 };

        public int[,] player_raise_chip_position = { { 212, 497 }, { 65, 386 }, { 64, 196}, { 163, 128}, { 260, 196}, { 260, 386} };
        public int[] raise_chip_size = { 36, 12 };
        public string[] player_raise_chip_color_range = { "bcc3c8-433C37", "99B8C4-66473B", "BECED5-41312A", "A4C6CE-5B3931", "A5BBC5-5A443A", "96AEB9-695146" };

        //Hero 下注/加注 的位置，有三个，对应不同的筹码量
        public int[,] hero_raise_chip_position = { { 94, 459 }, { 155, 459 }, {218, 459} };
        public int[] hero_raise_chip_position_size = { 45, 15 };
        public string[] hero_raise_chip_position_color_range = { "288CC2-0D141B" , "83B7CF-7C4830", "2385BC-0D1B22" };

        //底池的筹码
        public int[] public_chip_position = { 104, 459 };
        public int[] public_chip_position_size = { 30, 15 };
        public string[] public_chip_position_color_range = { "288CC2-0D141B" };
    }

    public class Config
    {
        public static string self_decision_stage_flag_color = "e13638";
        public static string self_not_decision_stage_flag_color = "a0a0a0";
    }

    public class Player
    {
        public string name = "";
        public int position = -1;
        public int chip = 0;
        public string action = "";
        public string card = "";
        public bool is_D = false;

        public Player()
        {
            name = "";
            position = -1;
            chip = 0;
            action = "";
            card = "";
            is_D = false;
        }
    }

    public class Message
    {
        public string hand = null;
        public int ante_chip = 0;
        public int blind_chip = 0;
        public int Hero_chip = 0;
        public int Villain_chip = 0;
        public string Hero_position = null;
        public string Hero_handcards = null;
        public string Hero_action = "";
        public string Villain_action = "";
        public string flop_board = null;
        public string turn_board = null;
        public string river_board = null;
        public bool new_hand = true;
        public string to_send = null;

        public bool flop_board_added = false;
        public bool turn_board_added = false;
        public bool river_board_added = false;

        public int which_player_stage = -1;
        public int villain_position = -1;

        public string public_card = null;

        public string poker_state = null;

        public int[] hero_can_raise_chip = { 0, 0, 0 };

        public string AI_return = null;

        public Message(string hand, int ante_chiip, int blind_chip)
        {
            this.hand = hand;
            this.ante_chip = ante_chiip;
            this.blind_chip = blind_chip;
            this.Hero_chip = 0;
            this.Villain_chip = 0;
            this.Hero_position = null;
            this.Hero_handcards = null;
            this.Hero_action = "";
            this.Villain_action = "";
            this.flop_board = null;
            this.turn_board = null;
            this.river_board = null;
            this.new_hand = true;
            this.flop_board_added = false;
            this.turn_board_added = false;
            this.river_board_added = false;
            this.which_player_stage = -1;
            this.villain_position = -1;
            this.public_card = null;
            this.poker_state = null;
            this.to_send = string.Format("{0} {1} {2}", this.hand, this.ante_chip, this.blind_chip);
            this.hero_can_raise_chip = new int[3] { 0, 0, 0 };
            this.AI_return = null;
    }

        public string add_message_to_send(string new_single_info)
        {
            this.to_send += string.Format(" {0}", new_single_info);
            return this.to_send;
        }
    }
}

